package org.xtext.runtime.interpreter;

import java.util.HashMap;
import java.util.Map;

public class ASTRAClassLoader {
	private static ASTRAClassLoader defaultClassLoader = new ASTRAClassLoader();

	public static ASTRAClassLoader getDefaultClassLoader() {
		return defaultClassLoader;
	}
	
	private Map<String, ASTRAClass> classes = new HashMap<String, ASTRAClass>();
	
	/**
	 * Loads the corrsponding astra class if it is not already loaded. if it is loaded, then
	 * it returns the current reference.
	 * 
	 * @param url
	 * @return
	 * @throws ASTRAClassNotFoundException
	 */
	public ASTRAClass loadClass(String _package, String url) throws ASTRAClassNotFoundException {
		
		ASTRAClass clazz = classes.get(url);
		if (clazz == null) {
			Class<?> c = null;
			try {
				c = Class.forName(url);
			} catch (ClassNotFoundException e) {
				if (_package != null) {
					String url2 = _package + "." + url;
					try {
						
						c = Class.forName(url2);
					} catch (ClassNotFoundException e1) {
						throw new ASTRAClassNotFoundException("Could not find ASTRA class: " + url2, e);
					}
				} else {
					throw new ASTRAClassNotFoundException("Could not find ASTRA class: " + url, e);
				}
			}
			
			if (c != null) {
				try {
					clazz = (ASTRAClass) c.newInstance();
				} catch (InstantiationException e) {
					throw new ASTRAClassNotFoundException("Could not load ASTRA class: " + url,e);
				} catch (IllegalAccessException e) {
					throw new ASTRAClassNotFoundException("Could not load ASTRA class: " + url,e);
				}
			}
			
			classes.put(url, clazz);
		}
		return clazz;
	}
}
